package com.njust.RateMyTray_backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njust.RateMyTray_backend.common.AuthenticationException;
import com.njust.RateMyTray_backend.common.CustomException;
import com.njust.RateMyTray_backend.common.InvalidPasswordException;
import com.njust.RateMyTray_backend.common.JwtUtils;
import com.njust.RateMyTray_backend.common.ResourceNotFoundException;
import com.njust.RateMyTray_backend.dto.LoginDTO;
import com.njust.RateMyTray_backend.dto.UserRegisterDTO;
import com.njust.RateMyTray_backend.dto.UserUpdateDTO;
import com.njust.RateMyTray_backend.entity.User;
import com.njust.RateMyTray_backend.mapper.UserMapper;
import com.njust.RateMyTray_backend.service.UserService;
import com.njust.RateMyTray_backend.vo.LoginVO;
import com.njust.RateMyTray_backend.vo.UserProfileVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private JwtUtils jwtUtils;

    @Override
    public User register(UserRegisterDTO userRegisterDTO) {
        // 1. 检查用户名是否已存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, userRegisterDTO.getUsername());
        if (this.count(queryWrapper) > 0) {
            throw new CustomException("用户名已存在");
        }

        // 2. 创建新用户
        User newUser = new User();
        newUser.setUsername(userRegisterDTO.getUsername());
        newUser.setNickname(userRegisterDTO.getUsername()); // 默认昵称和用户名相同
        newUser.setContactInfo(userRegisterDTO.getContactInfo());
        
        // 3. 密码加密 (前端应传递原文)
        String encryptedPassword = DigestUtils.md5DigestAsHex(userRegisterDTO.getPassword().getBytes());
        newUser.setPassword(encryptedPassword);

        // 4. 设置默认值
        newUser.setRole("user"); // 默认角色
        newUser.setStatus("active"); // 默认状态
        newUser.setCreatedAt(LocalDateTime.now());
        newUser.setUpdatedAt(LocalDateTime.now());

        // 5. 保存用户
        this.save(newUser);

        return newUser;
    }

    @Override
    public LoginVO login(LoginDTO loginDTO) {
        // 1. 根据用户名查询用户
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, loginDTO.getUsername());
        User user = this.getOne(queryWrapper);

        // 2. 用户不存在
        if (user == null) {
            throw new AuthenticationException("用户名或密码错误");
        }

        // 3. 密码比对 (前端应传递原文)
        String passwordFromRequest = DigestUtils.md5DigestAsHex(loginDTO.getPassword().getBytes());
        if (!user.getPassword().equals(passwordFromRequest)) {
            // 密码错误
            throw new AuthenticationException("用户名或密码错误");
        }

        // 4. 生成JWT
        String token = jwtUtils.generateToken(user.getUsername(), user.getRole(), user.getId());

        // 5. 构建VO
        return LoginVO.builder()
                .userId(user.getId())
                .username(user.getUsername())
                .role(user.getRole())
                .token(token)
                .build();
    }

    @Override
    public UserProfileVO getUserProfile(Long userId) {
        User user = this.getById(userId);

        if (user == null) {
            throw new ResourceNotFoundException("用户不存在");
        }

        return UserProfileVO.builder()
                .userId(user.getId())
                .username(user.getUsername())
                .nickname(user.getNickname())
                .avatarUrl(user.getAvatarUrl())
                .contactInfo(user.getContactInfo())
                .role(user.getRole())
                .build();
    }

    @Override
    public void updateUserProfile(Long userId, UserUpdateDTO userUpdateDTO) {
        User user = this.getById(userId);
        if (user == null) {
            throw new ResourceNotFoundException("用户不存在");
        }

        // 处理密码更新 (前端应传递原文)
        if (StringUtils.hasText(userUpdateDTO.getNewPassword())) {
            if (!StringUtils.hasText(userUpdateDTO.getOldPassword())) {
                throw new InvalidPasswordException("必须提供旧密码才能设置新密码");
            }

            // 对前端传来的旧密码原文进行加密，然后与数据库比对
            String encryptedOldPassword = DigestUtils.md5DigestAsHex(userUpdateDTO.getOldPassword().getBytes());
            if (!user.getPassword().equals(encryptedOldPassword)) {
                throw new InvalidPasswordException("旧密码不正确");
            }

            // 对前端传来的新密码原文进行加密，然后存储
            String encryptedNewPassword = DigestUtils.md5DigestAsHex(userUpdateDTO.getNewPassword().getBytes());
            user.setPassword(encryptedNewPassword);
        }

        // 处理其他字段
        if (StringUtils.hasText(userUpdateDTO.getNickname())) {
            user.setNickname(userUpdateDTO.getNickname());
        }
        if (StringUtils.hasText(userUpdateDTO.getAvatarUrl())) {
            user.setAvatarUrl(userUpdateDTO.getAvatarUrl());
        }
        if (StringUtils.hasText(userUpdateDTO.getContactInfo())) {
            user.setContactInfo(userUpdateDTO.getContactInfo());
        }

        user.setUpdatedAt(LocalDateTime.now());
        this.updateById(user);
    }
} 